#include "redis_util.h"

#include <drogon/drogon.h>
#include <memory>

std::optional<std::string> RedisUtil::getValue(const std::string &command) {
	std::mutex mutex;
	std::unique_lock<std::mutex> lock(mutex);
	std::condition_variable finished;
	std::optional<std::string> result;

	const auto redisClient = drogon::app().getRedisClient();

	redisClient->execCommandAsync(
			[&](const drogon::nosql::RedisResult &res) {
				if (!res.isNil())
					result = res.asString();

				finished.notify_all();
			},
			[&](const std::exception &e) {
				result = std::nullopt;
			},
			command);

	finished.wait(lock);

	return result;
}
std::optional<std::vector<std::string>> RedisUtil::keys(const std::string &key, int count) {
	std::mutex mutex;
	std::unique_lock<std::mutex> lock(mutex);
	std::condition_variable finished;
	std::optional<std::vector<std::string>> result;

	const auto redisClient = drogon::app().getRedisClient();

	redisClient->execCommandAsync(
			[&](const drogon::nosql::RedisResult &res) {
				if (!res.isNil()) {
					std::vector<drogon::nosql::RedisResult> res_vec = res.asArray();
					std::vector<drogon::nosql::RedisResult> key_vec = res_vec[1].asArray();

					if (!res_vec.empty()) {
						std::vector<std::string> str_vec;

						for (const auto &item : key_vec) {
							if (!item.isNil())
								str_vec.push_back(item.asString());
						}

						result = str_vec;
					}
				}

				finished.notify_all();
			},
			[&](const std::exception &e) {
				result = std::nullopt;
			},
			std::format("scan 0 match {} count {}", key, count));

	finished.wait(lock);

	return result;
}
